package com.morty.businessLog.sevice.impl;

import com.alibaba.fastjson.JSON;
import com.morty.businessLog.sevice.BusinessLogService;
import com.morty.config.CommonOptions;
import com.morty.config.model.TableModifyLog;
import com.morty.config.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.HttpAsyncResponseConsumerFactory;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class BusinessServiceImpl implements BusinessLogService {

	private static final RequestOptions COMMON_OPTIONS;

	public static final String INDEX_NAME = "pms_business_log";

	public static final String INDEX_TYPE = "es_data";

	@Resource
	private RestHighLevelClient client;

	static {
		RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();

		// 默认缓存限制为100MB，此处修改为30MB。
		builder.setHttpAsyncResponseConsumerFactory(
				new HttpAsyncResponseConsumerFactory
						.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024));
		COMMON_OPTIONS = builder.build();
	}

	/**
	 * 插入数据
	 * @param tableModifyLog  批量增加的数据
	 */
	@Override
	public int addIdxData(TableModifyLog tableModifyLog) {
		int status = 0;
		BulkRequest request = new BulkRequest();
		request.add(new IndexRequest(INDEX_NAME,INDEX_TYPE)
				.id(tableModifyLog.getLogId()).source(JSON.toJSONString(tableModifyLog), XContentType.JSON));
		try {
			BulkResponse bulk = client.bulk(request, COMMON_OPTIONS);
			status = bulk.status().getStatus();
			log.info("索引:{},插入数据成功!", INDEX_NAME);
		} catch (IOException e) {
			log.error(e.getMessage());
			log.error("索引:{},插入数据失败", INDEX_NAME);
		}
		return status;
	}


	/**
	 * 设置查询条件
	 * @param queryBuilder
	 * @param tableModifyLog
	 * @return
	 */
	public static BoolQueryBuilder setCondition (BoolQueryBuilder queryBuilder, TableModifyLog tableModifyLog) {
		// 操作用户
		if (StringUtils.isNotBlank(tableModifyLog.getOperator()))
			// 单个精确值检索
			queryBuilder.must(QueryBuilders.matchPhraseQuery("operator", tableModifyLog.getOperator()));
		// 方法名称
		if (StringUtils.isNotBlank(tableModifyLog.getMethodName()))
			// 模糊检索
			queryBuilder.must(QueryBuilders.fuzzyQuery("methodName", tableModifyLog.getMethodName()));
		return queryBuilder;
	}

	@Override
	public List<TableModifyLog> getByConditions(TableModifyLog tableModifyLog) throws Exception {
		List<TableModifyLog> results = new ArrayList<>();

		//设置查询
		BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
		queryBuilder = setCondition(queryBuilder, tableModifyLog);

		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
		searchSourceBuilder.query(queryBuilder);

		//设置排序
		searchSourceBuilder.sort("operationTime", SortOrder.DESC);

		SearchRequest searchRequest = new SearchRequest(INDEX_NAME).types(INDEX_TYPE);
		searchRequest.source(searchSourceBuilder);

		SearchResponse searchResponse = client.search(searchRequest, CommonOptions.COMMON_OPTIONS);
		SearchHits hits = searchResponse.getHits();
		SearchHit[] searchHits = hits.getHits();
		for (SearchHit hit : searchHits) {
			results.add((TableModifyLog) JsonUtil.mapToBean(hit.getSourceAsMap(), TableModifyLog.class));
		}
		return results;
	}

}
